home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
011-020
/
amok16
/
memsystem
/
memsystem.dok
< prev
next >
Wrap
Text File
|
1993-11-04
|
11KB
|
270 lines
======================================================================
Dokumentation zu "MemSystem" Version 1.3
Autor: Nicolas Benezan, Postwiesenstr. 2, D7000 Stuttgart 60
======================================================================
Kopierrecht
Das komplette Packet (Quelltext, Dokumentation und Objectcode) ist
Public Domain Software. Es darf beliebig kopiert und verbreitet werden
solange...
* mein Name und dieser Kopierrechtshinweis erhalten bleiben,
* die Vollständigkeit des ganzen Packets gewährleistet ist, und
* mit dem Vertrieb dieser Software kein Gewinn erwirtschaftet wird.
Die Kommerzielle Nutzung ohne meine ausdrückliche schriftliche
Genehmigung ist untersagt.
Ferner ist allen Personen, die in irgend einer Weise etwas mit "Data
Becker" zu tun haben, insbesondere für "Data Becker" arbeiten oder
deren Produkte verkaufen, jegliche Verwendung dieser Software verboten.
Verbesserungsvorschläge sind stets willkommen. Falls Sie Veränderungen
am Programm vornehmen, dokumentieren Sie diese bitte gut verständlich.
Es würde mich freuen, wenn Sie mich über größere Veränderungen in
Kenntnis setzen würden.
(c) 1988 by Nicolas Benezan.
Übersicht
* Umfang des Packets
* Einleitung
* Das Modul MemSystem
- Allocate, AllocMem, Deallocate
- NoCareAllocate, NoCareAllocMem, NoCareDeallocate
- MinMemory, Hysteresis
- EnterLevel, ExitLevel
* Das Modul ErrorReq
- YesNoRequest
- ErrHeader
- RecoverableExit
- DeadEndExit
- ExitQuiet
- Assert
* Das Modul TaskMemory
Umfang des Packet
Das komplette Packet "MemSystem" beinhaltet folgendes:
* MemSystem.dok Diese Dokumentation
* MemSystem.doc Englische Dokumentation
* MemSystem.def, -.mod, -.sym, -.obj V1.3
* ErrorReq.def, -.mod, -.sym, -.obj V1.2
* TaskMemory.def, -.mod, -.sym, -.obj V1.1
* TestMemSys.mod, -.obj Testmodul Quellcode, Objektdatei
* TestMemSys ausführbares Testprogramm
(Stand 29.Mar.1989)
Einleitung
MemSystem ist ein Speicherverwaltungsmodul, das gegenüber dem Standardmodul
"Heap" folgende Vorteile aufweist:
* es ist voll Multitaskingfähig, d.h. es kann vom Hauptmodul importiert und
von mehreren Tasks aus parallel benutzt werden. Dabei wird allozierter
Speicher immer in der MemList des aufrufenden Tasks eingetragen. Bei
Beendigung des Tasks (mit RemTask oder bei Process-Termination) wird der
gesammte mit MemSystem verwaltete Speicher freigegeben.
* Wird mehr Speicher angefordert als frei ist, wird dies nicht sofort mit
NIL beantwortet, sondern ein Requester (Retry/Cancel) erzeugt. Der Benutzer
hat somit die Möglichkeit, z.B. einige Workbench-Windows zu schließen, um
es dann noch einmal zu probieren. Der Programmieraufwand ist praktisch
null, entgegen der sonst üblichen Methode, dach jedem AllocMem() auf NIL zu
testen, den Requester anzuzeigen ...
* System-Deadlocks, die durch extremen Speichermangel hervorgerufen werden
können, werden verhindert. Viele Programme erzeugen bei Speichermangel eine
Meldung mit AutoRequest() (zB. auch der Modula-Compiler). Es wird aber oft
vergessen, daß der Requester selbst auch Speicher benötigt. MemSystem
berücksichtigt dies.
Neu: Version 1.3
----------------
Neu sind die Prozeduren NoCareAllocate, NoCareAllocMem und NoCareDeallocate,
die eine vereinfachte Fehlerbehandlung erlauben.
Dazugekommen ist außerdem die Levelbehandlung, die es ermöglicht, sämtlichen
in einer bestimmten Programmebene (Level) allozierten Speicher zurückzugeben.
Das Modul MemSystem
Dieses Modul ist sozusagen das Hauptmodul des Packets. Es exportiert die
High-Level-Prozeduren zur Speicherverwaltung und importiert die Module
ErrorReq und TaskMemory, welche die Low-Level-Prozeduren enthalten.
Allocate(), AllocMem(), Deallocate()
------------------------------------
Diese Prozeduren entsprechen in der Schnittstelle sowie in der Handhabung
genau den gleichnamigen Prozeduren von Heap. Allerdings läuft beim
allozieren von Speicher für das aufrufende Programm unsichtbar noch
folgendes ab:
* Es wird getestet, ob Size+MinMemory (siehe unten) Speicher frei ist.
* falls nicht wird ein Requester (Low Memory Warning Retry/Cancel) erzeugt.
Bei "Retry" wird noch einmal versucht, die angeforderte Speichermenge zur
Verfügung zu stellen. Bei "Cancel" wird NIL zurückgegeben, wie man es von
Heap bei Speichermangel kennt.
* falls doch wird der Speicher wie gewohnt alloziert. Der Speicherbereich
wird in der MemList des aufrufenden Tasks oder Prozesses registriert.
Einwandfreie Funktion ist auch bei mehreren parallellaufenden Tasks, die
auch unabhängig voneinander erzeugt und terminiert werden können,
gewährleistet. Die Prozeduren sind reentrant.
Ein Deallozieren von Speicher, den man gar nicht alloziert oder schon
freigegeben hat führt nicht zum Guru, sondern wird abgefangen.
NoCareAllocate(), NoCareAllocMem(), NoCareDeallocate()
------------------------------------------------------
Diese Prozeduren bewirken das gleiche wie die vorherigen, es entfällt
jedoch die Notwendigkeit, auf mögliche Fehler zu testen. Somit
vereinfacht sich die Programmierung. Die Prozeduren sollten jedoch
nicht aus Bequemlichkeit ständig verwendet werden - dadurch schafft
man nicht weniger sondern eher mehr Bugs! Verwenden Sie sie nur dort,
wo sie sinnvoll und notwendig sind!
NoCareAllocate() und NoCareAllocMem() bringen wie die normalen Allocate-
Prozeduren bei Speichermangel den Retry/Cancel Requester. Wird jedoch
Cancel gewählt wird das Programm abgebrochen (mit ErrorReq.ExitQuiet).
Man braucht deshalb nach NoCareAllocate() nicht auf NIL zu testen, sondern
kann davon ausgehen, daß der Speicher in jedem Fall zur Verfügung steht.
Dies ist vor allem bei kleinen Programmen sehr bequem.
Bei größeren, mit denen man Projekte bearbeiten kann, sollte jedoch darauf
verzichtet werden, und der umständliche Weg gewählt werden, damit man zum
Beispiel dem Benutzer noch ermöglichen kann, seine Arbeit zu speichern.
Denn es kommt leicht zu einem Wutausbruch, wenn ein Programm nach
mehrstündigem Arbeiten meint: "Not enough memory", und ohne Warnung
abbricht.
NoCareDeallocate() ist eine gutmütigere Version von Deallocate(), die
sich nicht beklagt, wenn Speicher mehrmals freigegeben wird.
Anwendungsbeispiel - verzeigerte Liste:
root --> node --> node --> node --> node --> NIL
| \ / |
| \ / |
| \ / |
V VV V
Data1 Data2 Data3
TYPE Node=RECORD
next:NodePtr;
data:DataPtr;
END;
node:=root
WHILE node#NIL DO
NoCareDeallocate(node^.data);
node:=node^.next;
END;
NoCareDeallocate() ist hier notwendig, weil zwei Nodes den
selben Datenbereich haben.
EnterLevel(), ExitLevel()
-------------------------
Speicher, der mit MemSystem alloziert wird, wird bei Beendigung des
Tasks/Programms automatisch freigegeben. Manchmal ist es jedoch
wünschenswert schon vorher bestimmte Teile davon freizugeben.
Zum Beispiel soll eine Prozedur am Ende allen Speicher freigeben, den
sie alloziert hat. Dies ist möglich, wenn an deren Anfang EnterLevel()
und am Schluß ExitLevel() steht. Mit ExitLevel wird dann der Speicher
freigegeben, der seit dem zugehörigen EnterLevel() alloziert wurde.
ExitLevel() verläßt automatisch auch alle tieferen Level. Beispiel:
VAR Inner,Outer:LevelKey;
...
EnterLevel(Outer);
...
EnterLevel(Inner);
jetzt wäre
ExitLevel(Outer);
gleichbedeutend mit
ExitLevel(Inner);
ExitLevel(Outer);
Jedem Level wird mit EnterLevel() ein (für diesen Task) eindeutiger
Schlüssel (opaker Typ LevelKey) vergeben.
MinMemory
---------
gibt die größe des Speichers an, der minimal noch freibleiben muß, damit
die korrekte Funktion des Systems gewährleistet ist. Default ist 20kB, was
für einige Notfall-Requester oder Alerts ausreicht.
Hysteresis
----------
Damit nach einem Speichermangel wieder Speicher alloziert werden kann, muß
mindestens minMemory+Hysteresis Speicher frei sein. Die Hysterese wurde
eingeführt, damit bei einem Arbeiten an der minMemory-Grenze nicht all paar
Sekunden ein Requester erscheint, sondern der Speicher nach einem
erfolgreichen "Retry" wieder für eine Weile reicht. Default ist 30kB.
Das Modul ErrorReq
Dieses Modul wird von MemSystem benutzt und beinhaltet einige nützliche
Prozeduren zum Anzeigen von einfachen Requestern und zum Abbrechen des
Programms.
YesNoRequest()
--------------
Dies ist eine Vereinfachung von Intuition.AutoRequest(). Sie wird intern von
Allocate, AllocMem (bei Speichermangel) und von RecoverableExit verwendet.
Als "Zugabe" wurde die Prozedur auch im Definition-Module aufgeführt und
somit für jedermann zugänglich gemacht. Die Parameter dürften
selbsterklärend sein (siehe auch Arts.Request() ).
ErrHeader()
-----------
Ist die Überschrift jedes Requesters, der von ErrorReq erzeugt wird
(Default ist "Modula-2 Error Handler").
RecoverableExit()
-----------------
Dies ist gewissermaßen die Kombination aus Arts.BreakPoint und Arts.Error.
Während BreakPoint nach beantworten des Requesters immer weitermacht, und
Error immer abbricht, kann der Benutzer bei RecoverableExit selbst
entscheiden.
Die Prozedur verwndet die Variable ErrHeader (siehe dort).
DeadEndExit()
-------------
Entspricht Arts.Error, mit dem Unterschied, daß nicht die häßliche Meldung
"Modula-2 Programmunterbruch" erscheint. Stattdessen wird ErrHeader
und darunter der angegebene Text angezeigt.
ExitQuiet()
-----------
ermöglicht das korrekte beenden des Programms von jeder beliebigen Stelle
aus. Ebenso wie auch bei DeadEndExit und RecoverableExit funktioniert
hierbei der TermProcedure-Mechanismus ordnungsgemäß.
Assert()
--------
ist dem Assert von Arts ähnlich. Wenn die zu überprüfende Bedingung FALSE
ist, wird eine Meldung ausgegeben und Das Programm abgebrochen. Wurde
das Programm von der Workbench gestartet, wird ein DeadEndExit-Requester
erzeugt, ansonsten der Text direkt im CLI-Fenster ausgegeben.
Das Modul TaskMemory
Dieses Modul beinhaltet die Low-Level-Prozeduren für MemSystem. Sie
wurden vom Hauptmodul getrennt, um zu verhindern, daß sehr kleine
Programme, die die umfangreichen Funktionen von MemSystem nicht benötigen,
sich unnötig aufblähen, weil wegen wenigen Prozeduren ein riesiges
Modul dazugelinkt wird.
Die Prozeduren sind wie die von MemSystem reentrant und voll multitasking-
fähig. Sie unterstützen jedoch keine Requester und geben bei einem
Fehlschlag wie die Exec- und Heap-Prozeduren einfach NIL zurück.
AllocTaskMem() ist zu Exec.AllocMem() parameterkompatibel, Allocate(),
AllocMem() und Deallocate() jeweils zu der entsprechenden Heap-Prozedur.